package com.wang.socket;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import com.wang.pojo.ChatMsg;
import com.wang.utils.JwtUtils;
import com.wang.utils.SpringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


@Component
@ServerEndpoint(value = "/xinxinchat")
public class MyWebSocketServer {

    private static final Logger log= LoggerFactory.getLogger(MyWebSocketServer.class);

    //记录当前在线连接数
    public static final Map<String, Session> sessions=new ConcurrentHashMap<>();

    private StringRedisTemplate stringRedisTemplate(){
        return SpringUtils.getBean(StringRedisTemplate.class);
    }


    //连接建立成功调用的方法
    @OnOpen
    public void onOpen(Session session) throws IOException {

        String token = session.getRequestParameterMap().get("token").get(0);
        Jws<Claims> claimsJws = JwtUtils.parseJwt(token);

        //用户名
        String username = (String) claimsJws.getBody().get("username");
        String roles = (String) claimsJws.getBody().get("roles");
        String redisListKey1 = null;
        String redisListKey2 = null;
        if("user".equals(roles)){
            redisListKey1="OnlineUser";
            redisListKey2="OnlineHelper";
        }else if("helper".equals(roles)){
            redisListKey1="OnlineHelper";
            redisListKey2="OnlineUser";
        }
        //
        stringRedisTemplate().boundZSetOps(redisListKey1).add(username,1);

        //向前台发送在线列表
        session.getBasicRemote().sendText(JSON.toJSONString(
                        new ChatMsg()
                .setType(ChatMsg.Type.onlineList)
                .setData(ImmutableMap.of(
                        "list",stringRedisTemplate().boundZSetOps(redisListKey2).range(0,-1),
                        "key",redisListKey2
                ))
                ));

        //上线提醒
        sendAllMessage(
                JSON.toJSONString(new ChatMsg()
                .setType(ChatMsg.Type.online)
                .setData(ImmutableMap.of( //不可变map
                        "username",username,
                        "roles",roles
                )))
        );

        sessions.put(username,session);

    }

    //连接关闭调用的方法
    @OnClose
    public void onClose(Session session){
        String token = session.getRequestParameterMap().get("token").get(0);
        Jws<Claims> claimsJws = JwtUtils.parseJwt(token);

        //用户名
        String username = (String) claimsJws.getBody().get("username");
        sessions.remove(username);
    }

    //服务端接收到客户端的消息
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println(message);
    }


    /**
     * 服务端发送消息给所有客户端
     */
    public void sendAllMessage(String message) throws IOException {
        for (Session session : sessions.values()) {
            log.info("服务端给客户端[{}]发送消息{}", session.getId(), message);
            session.getBasicRemote().sendText(message);
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("LoginResultWebSocket 发⽣错误");
        error.printStackTrace();
    }


}
